const { getToken, getJWTPayload } = require('../middlewares/jwt');
const md5 = require('md5');
const { getRuleList, adminUserRules } = require('../services/rule');
const adminModel = require('../model/admin');
const menuModel = require('../model/menu');
const ruleModel = require('../model/rule');
const { updateSqlParse } = require('../common/utils');
const { connect } = require("../model/index");

/**
 * 获取菜单列表
 * @method: get
 * @param {*} ctx
 * @param {*} next
 */
const getMenuList = async (ctx, next) => {
  const query = ctx.request.query;
  const pageSize = Number(query.pageSize || 10);
  const pageNum = Number(query.pageNum || 1) - 1;
  const database = ruleModel.TABLE_NAME;
  let [rows, fields] = await connect.query(
    `select * from ${database} where status = ? order by id desc limit ? offset ?`,
    [1, pageSize, pageNum * pageSize]
  );
  let [countRows] = await connect.query(
    `select count(id) as count from ${database} where status = ?`,
    [1]
  );
  const pageCount = Math.ceil(countRows[0].count / pageSize); // 总页数
  ctx.body = {
    data: {
      datas: rows,
      pageNum: pageNum + 1,
      pageSize: pageSize,
      pageCount: pageCount,
      total: countRows[0].count || 0
    },
    code: 200,
    msg: '查询成功',
  };
  await next();
};

/**
 * 添加菜单
 * @method: post
 * @param {*} ctx
 * @param {*} next
 */
const addMenu = async (ctx, next) => {
  const query = ctx.request.body;
  const saveData = {
    title: query.title,
    url: query.url,
    pid: query.pid, // 上级id
    menu_type: query.menu_type, // 菜单类型
    status: 1,
  };
  let fields = [];
  let values = [];
  for (let key in saveData) {
    if (key != 'id') {
      fields.push(key);
      values.push(`'${saveData[key]}'`);
    }
  }

  const database = ruleModel.TABLE_NAME;
  const connection = await connect.getConnection();
  
  try {
    // 开启事务
    await connection.beginTransaction();
    
    await connection.query(
      `
        INSERT INTO ${database}
        (${fields.join(',')})
        VALUES (${values.join(',')})
      `
    );
    await connection.commit();
  } catch (err) {
    await connection.rollback();
    ctx.throw(new Error(err));
  } finally {
    // connection.releaseConnection();
    connection.release();
  }

  ctx.body = {
    data: null,
    code: 200,
    msg: '操作成功',
  };
  await next();
};

/**
 * 修改菜单
 * @method: post
 * @param {*} ctx
 * @param {*} next
 */
const saveMenu = async (ctx, next) => {
  const query = ctx.request.body;
  const saveData = {
    title: query.title,
    url: query.url,
    pid: query.pid,
  };
  let sqlArr = [];
  for (let key in saveData) {
    if (key != 'id') {
      sqlArr.push(`${key}='${saveData[key]}'`);
    }
  }

  const database = menuModel.TABLE_NAME;
  const connection = await connect.getConnection();

  try {
    // 开启事务
    await connection.beginTransaction();

    await connection.query(
      `
        UPDATE ${database}
        SET ${sqlArr.join(',')}
        WHERE id = ? and status = 1
      `,
      [Number(query.id)]
    );
    await connection.commit();
  } catch (err) {
    await connection.rollback();
    ctx.throw(new Error(err));
  } finally {
    // connection.releaseConnection();
    connection.release();
  }

  ctx.body = {
    data: {},
    code: 200,
    msg: '操作成功',
  };
  await next();
};

/**
 * 添加管理员用户
 * @method: post
 * @param {*} ctx
 * @param {*} next
 */
const addAdmin = async (ctx, next) => {
  const query = ctx.request.body;
  const saveData = {
    username: query.username, // 账号
    group_id: query.group_id, // 角色
    mobile: query.mobile,
    realname: query.realname, // 用户姓名
    status: 1,
    password: md5('123456'),
    create_time: Math.floor(Date.now() / 1000),
  };
  let fields = [];
  let values = [];
  for (let key in saveData) {
    if (key != 'id') {
      fields.push(key);
      values.push(`'${saveData[key]}'`);
    }
  }

  const database = adminModel.TABLE_NAME;
  const connection = await connect.getConnection();

  try {
    // 开启事务
    await connection.beginTransaction();

    await connection.query(
      `
        INSERT INTO ${database}
        (${fields.join(',')})
        VALUES (${values.join(',')})
      `
    );
    await connection.commit();
  } catch (err) {
    await connection.rollback();
    ctx.throw(new Error(err));
  } finally {
    // connection.releaseConnection();
    connection.release();
  }

  ctx.body = {
    data: null,
    code: 200,
    msg: '操作成功',
  };
  await next();
};

/**
 * 修改管理员信息
 * @method: post
 * @param {*} ctx
 * @param {*} next
 */
const updateAdmin = async (ctx, next) => {
  const query = ctx.request.body;
  const saveData = {
    username: query.username, // 账号
    group_id: query.group_id, // 角色
    mobile: query.mobile,
    realname: query.realname, // 用户姓名
  };
  let sqlArr = [];
  for (let key in saveData) {
    if (key != 'id') {
      sqlArr.push(`${key}='${saveData[key]}'`);
    }
  }

  const database = adminModel.TABLE_NAME;
  const connection = await connect.getConnection();

  try {
    // 开启事务
    await connection.beginTransaction();

    await connection.query(
      `
        UPDATE ${database}
        SET ${sqlArr.join(',')}
        WHERE id = ? and status = 1
      `,
      [Number(query.id)]
    );
    await connection.commit();
  } catch (err) {
    await connection.rollback();
    ctx.throw(new Error(err));
  } finally {
    // connection.releaseConnection();
    connection.release();
  }

  ctx.body = {
    data: {},
    code: 200,
    msg: '操作成功',
  };
  await next();
};

/**
 * 删除管理员
 * @method: get
 * @param {*} ctx 
 * @param {*} next 
 */
const deleteAdminById = async (ctx, next) => {
  const query = ctx.request.query;
  const id = query.id;

  const database = adminModel.TABLE_NAME;
  const connection = await connect.getConnection();

  try {
    // 开启事务
    await connection.beginTransaction();

    await connection.query(
      `
        DELETE FROM ${database}
        where id = ?
      `,
      [id]
    );
    await connection.commit();
  } catch(err) {
    await connection.rollback();
    ctx.throw(new Error(err));
  } finally {
    // connection.releaseConnection();
    connection.release();
  }

  ctx.body = {
    data: {},
    code: 200,
    msg: '操作成功',
  };
  await next();
};

/**
 * 获取管理员列表
 * @method: get
 * @param {*} ctx
 * @param {*} next
 */
const getAdminList = async (ctx, next) => {
  const query = ctx.request.query;
  const pageSize = Number(query.pageSize || 10);
  const pageNum = Number(query.pageNum || 1) - 1;
  const database = adminModel.TABLE_NAME;
  let [rows, fields] = await connect.query(
    `
    select
      id,
      username,
      email,
      group_id,
      mobile,
      realname,
      remark,
      status
    from
      ${database}
    where
      status = ?
    order by
      id desc
    limit ? offset ?
  `,
    [1, pageSize, pageNum * pageSize]
  );
  let [countRows] = await connect.query(
    `select count(*) as count from ${database} where status = ?`,
    [1]
  );
  const pageCount = Math.ceil(countRows[0].count / pageSize); // 总页数
  ctx.body = {
    data: {
      datas: rows,
      pageNum: pageNum + 1,
      pageSize: pageSize,
      pageCount: pageCount,
      total: countRows[0].count || 0
    },
    code: 200,
    msg: '查询成功',
  };
  await next();
};

/**
 * 修改管理员账号密码
 * @method: post
 * @param {*} ctx
 * @param {*} next
 */
const updateAdminPassword = async (ctx, next) => {
  const query = ctx.request.body;
  const saveData = {
    password: md5(String(query.password)), // 密码
  };

  const sqlArr = updateSqlParse(saveData);

  const database = adminModel.TABLE_NAME;
  const connection = await connect.getConnection();

  try {
    // 开启事务
    await connection.beginTransaction();

    await connection.query(
      `
        UPDATE ${database}
        SET ${sqlArr.join(',')}
        WHERE id = ? and status = 1
      `,
      [Number(query.id)]
    );
    await connection.commit();
  } catch (err) {
    await connection.rollback();
    ctx.throw(new Error(err));
  } finally {
    // connection.releaseConnection();
    connection.release();
  }

  ctx.body = {
    data: {},
    code: 200,
    msg: '操作成功',
  };
  await next();
};

/**
 * 后台登录
 * @method: post
 * @param {*} ctx
 * @param {*} next
 */
const login = async (ctx, next) => {
  const query = ctx.request.body;
  const password = md5(String(query.password));
  const database = adminModel.TABLE_NAME;
  let [rows, fields] = await connect.query(
    `select id, username, realname from ${database} where username = ? and password = ?`,
    [query.username, password]
  );
  if (rows[0]) {
    // 查询所有权限
    let { list: ruleList } = await getRuleList({
      pageNum: 1,
      pageSize: 999,
    });
    // 查询所属用户的权限
    let { auth } = await adminUserRules({
      id: rows[0].id,
    });
    const menuList = [];
    const authList = [];
    auth = auth[0].rules ? auth[0].rules : '';
    auth = auth.split(',');
    ruleList = ruleList.forEach(item => {
      if ((auth.includes(String(item.id)) || rows[0].id == 1) && item.is_menu == 1) {
        menuList.push(item);
      }

      if ((auth.includes(String(item.id)) || rows[0].id == 1) && item.is_menu == 0) {
        authList.push(item);
      }
    });
    ctx.body = {
      code: 200,
      msg: '登录成功',
      data: {
        token: getToken({
          username: query.username,
          password: query.password,
        }),
        menu: menuList,
        auth: authList,
        userInfo: rows[0]
      },
    };
  } else {
    ctx.body = {
      code: 302,
      data: null,
      msg: '密码错误或账号不存在',
    };
  }

  await next();
};

module.exports = {
  getMenuList,
  addMenu,
  saveMenu,
  addAdmin,
  updateAdmin,
  deleteAdminById,
  getAdminList,
  updateAdminPassword,
  login,
};
